'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: fcopy.n,v 1.2 2003/11/24 05:09:59 bbbush Exp $
'\" 
'\" The definitions below are for supplemental macros used in Tcl/Tk
'\" manual entries.
'\"
'\" .AP type name in/out ?indent?
'\"	Start paragraph describing an argument to a library procedure.
'\"	type is type of argument (int, etc.), in/out is either "in", "out",
'\"	or "in/out" to describe whether procedure reads or modifies arg,
'\"	and indent is equivalent to second arg of .IP (shouldn't ever be
'\"	needed;  use .AS below instead)
'\"
'\" .AS ?type? ?name?
'\"	Give maximum sizes of arguments for setting tab stops.  Type and
'\"	name are examples of largest possible arguments that will be passed
'\"	to .AP later.  If args are omitted, default tab stops are used.
'\"
'\" .BS
'\"	Start box enclosure.  From here until next .BE, everything will be
'\"	enclosed in one large box.
'\"
'\" .BE
'\"	End of box enclosure.
'\"
'\" .CS
'\"	Begin code excerpt.
'\"
'\" .CE
'\"	End code excerpt.
'\"
'\" .VS ?version? ?br?
'\"	Begin vertical sidebar, for use in marking newly-changed parts
'\"	of man pages.  The first argument is ignored and used for recording
'\"	the version when the .VS was added, so that the sidebars can be
'\"	found and removed when they reach a certain age.  If another argument
'\"	is present, then a line break is forced before starting the sidebar.
'\"
'\" .VE
'\"	End of vertical sidebar.
'\"
'\" .DS
'\"	Begin an indented unfilled display.
'\"
'\" .DE
'\"	End of indented unfilled display.
'\"
'\" .SO
'\"	Start of list of standard options for a Tk widget.  The
'\"	options follow on successive lines, in four columns separated
'\"	by tabs.
'\"
'\" .SE
'\"	End of list of standard options for a Tk widget.
'\"
'\" .OP cmdName dbName dbClass
'\"	Start of description of a specific option.  cmdName gives the
'\"	option's name as specified in the class command, dbName gives
'\"	the option's name in the option database, and dbClass gives
'\"	the option's class in the option database.
'\"
'\" .UL arg1 arg2
'\"	Print arg1 underlined, then print arg2 normally.
'\"
'\" RCS: @(#) $Id: fcopy.n,v 1.2 2003/11/24 05:09:59 bbbush Exp $
'\"
'\"	# Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
.if t .wh -1.3i ^B
.nr ^l \n(.l
.ad b
'\"	# Start an argument description
.de AP
.ie !"\\$4"" .TP \\$4
.el \{\
.   ie !"\\$2"" .TP \\n()Cu
.   el          .TP 15
.\}
.ta \\n()Au \\n()Bu
.ie !"\\$3"" \{\
\&\\$1	\\fI\\$2\\fP	(\\$3)
.\".b
.\}
.el \{\
.br
.ie !"\\$2"" \{\
\&\\$1	\\fI\\$2\\fP
.\}
.el \{\
\&\\fI\\$1\\fP
.\}
.\}
..
'\"	# define tabbing values for .AP
.de AS
.nr )A 10n
.if !"\\$1"" .nr )A \\w'\\$1'u+3n
.nr )B \\n()Au+15n
.\"
.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
.nr )C \\n()Bu+\\w'(in/out)'u+2n
..
.AS Tcl_Interp Tcl_CreateInterp in/out
'\"	# BS - start boxed text
'\"	# ^y = starting y location
'\"	# ^b = 1
.de BS
.br
.mk ^y
.nr ^b 1u
.if n .nf
.if n .ti 0
.if n \l'\\n(.lu\(ul'
.if n .fi
..
'\"	# BE - end boxed text (draw box now)
.de BE
.nf
.ti 0
.mk ^t
.ie n \l'\\n(^lu\(ul'
.el \{\
.\"	Draw four-sided box normally, but don't draw top of
.\"	box if the box started on an earlier page.
.ie !\\n(^b-1 \{\
\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.el \}\
\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.\}
.fi
.br
.nr ^b 0
..
'\"	# VS - start vertical sidebar
'\"	# ^Y = starting y location
'\"	# ^v = 1 (for troff;  for nroff this doesn't matter)
.de VS
.if !"\\$2"" .br
.mk ^Y
.ie n 'mc \s12\(br\s0
.el .nr ^v 1u
..
'\"	# VE - end of vertical sidebar
.de VE
.ie n 'mc
.el \{\
.ev 2
.nf
.ti 0
.mk ^t
\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
.sp -1
.fi
.ev
.\}
.nr ^v 0
..
'\"	# Special macro to handle page bottom:  finish off current
'\"	# box/sidebar if in box/sidebar mode, then invoked standard
'\"	# page bottom macro.
.de ^B
.ev 2
'ti 0
'nf
.mk ^t
.if \\n(^b \{\
.\"	Draw three-sided box if this is the box's first page,
.\"	draw two sides but no top otherwise.
.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.\}
.if \\n(^v \{\
.nr ^x \\n(^tu+1v-\\n(^Yu
\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
.\}
.bp
'fi
.ev
.if \\n(^b \{\
.mk ^y
.nr ^b 2
.\}
.if \\n(^v \{\
.mk ^Y
.\}
..
'\"	# DS - begin display
.de DS
.RS
.nf
.sp
..
'\"	# DE - end display
.de DE
.fi
.RE
.sp
..
'\"	# SO - start of list of standard options
.de SO
.SH "STANDARD OPTIONS"
.LP
.nf
.ta 5.5c 11c
.ft B
..
'\"	# SE - end of list of standard options
.de SE
.fi
.ft R
.LP
See the \\fBoptions\\fR manual entry for details on the standard options.
..
'\"	# OP - start of full description for a single option
.de OP
.LP
.nf
.ta 4c
Command-Line Name:	\\fB\\$1\\fR
Database Name:	\\fB\\$2\\fR
Database Class:	\\fB\\$3\\fR
.fi
.IP
..
'\"	# CS - begin code excerpt
.de CS
.RS
.nf
.ta .25i .5i .75i 1i
..
'\"	# CE - end code excerpt
.de CE
.fi
.RE
..
.de UL
\\$1\l'|0\(ul'\\$2
..
.TH fcopy 3tcl 8.0 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
fcopy \- 从一个通道向另一个复制数据
.SH "总览 SYNOPSIS"
\fBfcopy \fIinchan\fR \fIoutchan\fR ?\fB\-size \fIsize\fR? ?\fB\-command \fIcallback\fR?
.BE

.SH "描述 DESCRIPTION"
.PP
\fBfcopy\fR  命令从一个 I/O 通道 \fIinchan\fR  向另一个 I/O 通道 \fIoutchan\fR  
复制数据。\fBfcopy\fR  命令在 Tcl I/O 系统中起到缓冲的杠杆作用(leverage)，它避免额外的复制，并且在向慢速目标如网络套接口复制大文件的时候避免在主存中缓冲过多的数据。
.PP
 \fBfcopy\fR 命令从 \fIinchan\fR  传输数据直到文件结束或传输完 \fIsize\fR字节。如果没有给出 \fB-size\fR 参数，则复制持续到文件结束。从 \fIinchan\fR读的所有数据都复制到 \fIoutchan\fR。如果没有 \fB-command\fR选项，在复制完成并返回写到 \fIoutchan \fR的字节数之前 \fBfcopy\fR  将阻塞。
.PP
\fB-command\fR 参数使 \fBfcopy\fR在后台工作。在这种情况下它立即返回，并在复制完成时调用  \fIcallback\fR。调用 \fIcallback\fR 加上一个或两个额外的参数来指示有多少字节被写到了 \fIoutchan\fR。在后台复制期间如果发生了一个错误，第二个参数是与错误相关联的错误字符串。使用后台复制不需要把 \fIinchan\fR 或 \fIoutchan\fR 转换成非阻塞模式；\fBfcopy\fR 命令将自动关照这些。但是，需要使用 \fBvwait\fR 命令或使用 Tk 进入事件循环。
.PP
在后台复制期间不允许对 \fIinchan\fR 或 \fIoutchan \fR做其他 I/O 操作。如果在复制进行期间 \fIinchan\fR 或 \fIoutchan\fR  中被关闭，停止当前的复制并且不做命令回调。如果 \fIinchan\fR被关闭，则写出为 \fIoutchan\fR  而排队(queue)的所有数据。
.PP
注意在一个命令复制期间 \fIinchan\fR 可以变成可读的。在一个后台复制期间你应该关闭任何 \fBfileevent\fR句柄，这样这些句柄不与复制相触及(interfere)。通过一个 \fBfileevent\fR句柄的任何 I/O 尝试将得到一个 "channel busy"  错误。
.PP
.PP
\fBFcopy\fR  依据 \fIinchan\fR 和 \fIoutchan \fR的 \fB-translation\fR选项来转换它们中的文件行结束序列。参见\fBfconfigure\fR的手册条目来得到 \fB-translation\fR  选项的详情。转换意味着从 \fIinchan\fR 读到的字节数与写到 \fIoutchan\fR.的字节数可能不同。只报告写到 \fIoutchan\fR中的字节数。要么作为同步的 \fBfcopy\fR 的返回值，要么作为给异步的 \fBfcopy \fR的回调的参数。  

.SH "范例 EXAMPLE"
.PP
第一个例子展示了回调如何得到传递给它的传输了的字节数。它还使用 vwait  来使应用进入事件循环。当然，不使用回调也能做出这个简化了的例子。
.DS
proc Cleanup {in out bytes {error {}}} {
    global total
    set total $bytes
    close $in
    close $out
    if {[string length $error] != 0} {
	# error occurred during the copy
    }
}
set in [open $file1]
set out [socket $server $port]
fcopy $in $out -command [list Cleanup $in $out]
vwait total

.DE
.PP
第二个例子按块(chunk)复制并在命令回调中测试文件结束。  
.DS
proc CopyMore {in out chunk bytes {error {}}} {
    global total done
    incr total $bytes
    if {([string length $error] != 0) || [eof $in] {
	set done $total
	close $in
	close $out
    } else {
	fcopy $in $out -command [list CopyMore $in $out $chunk] \\
	    -size $chunk
    }
}
set in [open $file1]
set out [socket $server $port]
set chunk 1024
set total 0
fcopy $in $out -command [list CopyMore $in $out $chunk] -size $chunk
vwait done

.DE

.SH "参见 SEE ALSO"
eof(n), fblocked(n), fconfigure(n)

.SH "关键字 KEYWORDS"
blocking, channel, end of line, end of file, nonblocking, read, translation

.SH "[中文版维护人]"
.B 寒蝉退士
.SH "[中文版最新更新]"
.B 2001/08/02
.SH "《中国 Linux 论坛 man 手册页翻译计划》:"
.BI http://cmpp.linuxforum.net
